package com.coder.oj.admin.service;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.coder.oj.admin.dto.KeyValueDto;
import com.coder.oj.admin.dto.ProblemDto;
import com.coder.oj.admin.mapstruct.ProblemMapstruct;
import com.coder.oj.admin.query.ProblemQuery;
import com.coder.oj.admin.vo.ProblemVo;
import com.coder.oj.common.core.JsonPage;
import com.coder.oj.common.core.R;
import com.coder.oj.common.entity.Case;
import com.coder.oj.common.entity.Commit;
import com.coder.oj.common.entity.Problem;
import com.coder.oj.common.enums.CommonStatusEnum;
import com.coder.oj.common.exception.DataException;
import com.coder.oj.common.mapper.AdminMapper;
import com.coder.oj.common.mapper.CaseMapper;
import com.coder.oj.common.mapper.CommitMapper;
import com.coder.oj.common.mapper.ProblemMapper;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Bosen 2022/11/28 11:50
 */
@Service
public class ProblemService {

    @Autowired
    private AdminMapper adminMapper;

    @Autowired
    private ProblemMapper problemMapper;

    @Autowired
    private ProblemMapstruct problemMapstruct;

    @Autowired
    private CaseMapper caseMapper;

    @Autowired
    private CommitMapper commitMapper;

    /**
     * 分页查询
     * @author Bosen 2022/12/16 10:05
     **/
    public JsonPage<ProblemVo> getProblemPage(ProblemQuery params) {
        LambdaQueryWrapper<Problem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ObjectUtils.isNotEmpty(params.getStatus()), Problem::getStatus, params.getStatus());
        queryWrapper.like(StringUtils.isNotBlank(params.getName()), Problem::getName, params.getName());
        queryWrapper.like(StringUtils.isNotBlank(params.getSource()), Problem::getSource, params.getSource());
        queryWrapper.like(StringUtils.isNotBlank(params.getContent()), Problem::getContent, params.getContent());
        queryWrapper.eq(StringUtils.isNotBlank(params.getDifficulty()), Problem::getDifficulty, params.getDifficulty());
        IPage<Problem> page = problemMapper.selectPage(new Page<>(params.getPage(), params.getPageSize()), queryWrapper);
        List<ProblemVo> collect = page.getRecords().stream().map(problem -> {
            ProblemVo vo = problemMapstruct.toVO(problem);
            vo.setCreateBy(adminMapper.getAdminName(problem.getCreateBy()));
            vo.setUpdateBy(adminMapper.getAdminName(problem.getUpdateBy()));
            return vo;
        }).collect(Collectors.toList());
        return new JsonPage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect);
    }

    /**
     * 更新题目
     * @author Bosen 2023/1/22 13:29
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateProblem(ProblemDto params) {
        // 删除原先的case
        caseMapper.delete(Wrappers.lambdaQuery(Case.class)
                .eq(Case::getProblemId, params.getId())
        );
        // 更新case
        if(CollectionUtils.isNotEmpty(params.getCases())) {
            params.getCases().forEach(item -> {
                Case zase = new Case();
                zase.setInput(item.getKey());
                zase.setOutput(item.getValue());
                zase.setProblemId(params.getId());
                caseMapper.insert(zase);
            });
        }
        problemMapper.updateById(problemMapstruct.toEntity(params));
    }

    /**
     * 删除题目
     * @author Bosen 2023/1/22 14:43
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteProblem(Long id) {
        // 特判
        int count = commitMapper.selectCount(Wrappers.lambdaQuery(Commit.class)
                .eq(Commit::getProblemId, id));
        if(count > 0) throw new DataException("此题目不可删除");
        // 删除case
        caseMapper.delete(Wrappers.lambdaQuery(Case.class)
                .eq(Case::getProblemId, id));
        // 删除题目
        problemMapper.deleteById(id);
    }
}
